package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.*;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class TextFileUtils {
    public static String read(File f, String charset) throws Exception {
        FileInputStream fstream = new FileInputStream(f);
        try {
            int fileSize = (int) f.length();
//            if (fileSize > (1024 * 512))
//                throw new Exception("File too large to read! size=" + fileSize);

            byte[] buffer = new byte[fileSize];
            // 读取到字符数组里
            fstream.read(buffer);
            return new String(buffer, charset);
        } finally {
            try {
                fstream.close();
            } catch (Exception e) {
            }
        }
    }

    public static void write(File f, String text, String charset) throws Exception {
        FileOutputStream fstream = new FileOutputStream(f);
        try {
            fstream.write(text.getBytes(charset));
        } finally {
            fstream.close();
        }
    }

    public static String SearchKeyword(File file, String keyword, String keyIndex, Boolean matchCase) {
        //参数校验
        verifyParam(file, keyword);

        //行读取
        LineNumberReader lineReader = null;
        StringBuilder sb = new StringBuilder();
        Integer totalTimes = 0;
        try {
            lineReader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "GBK"));
            String readLine = null;
            while ((readLine = lineReader.readLine()) != null) {
                if (!readLine.startsWith(keyIndex)) {
                    continue;
                }
                lineReader.getLineNumber();
                //判断每一行中,出现关键词的次数
                int index = 0;
                int next = 0;
                int times = 0;//出现的次数
                //判断次数
                if (matchCase == true) {
                    readLine = readLine.toUpperCase();
                    keyword = keyword.toUpperCase();
                }
                while ((index = readLine.indexOf(keyword, next)) != -1) {
                    next = index + keyword.length();
                    times++;
                    totalTimes++;
                }
                if (times > 0) {
                    sb.append("第" + lineReader.getLineNumber() + "行" + "出现 " + keyword + " 次数: " + times + "\n");
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            close(lineReader);
        }
        sb.insert(0, "在索引【" + keyIndex + "】下总共出现" + "出现 " + keyword + " 次数: " + totalTimes + "\n");
        return sb.toString();
    }

    public static String searchWordByKeyIndex(File file, String keyIndex, List<String> listWords) {
        //参数校验
        verifyParam(file);
        StringBuilder sb = new StringBuilder();
        //行读取
        LineNumberReader lineReader = null;
        try {
            lineReader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
            String readLine = null;
            boolean readFlag = false;
            while ((readLine = lineReader.readLine()) != null) {
                if (readLine.startsWith(keyIndex)) {
                    readFlag = true;
                }
                if (readFlag == true) {
                    for (String index : listWords) {
                        if (readLine.startsWith(index) && !readLine.startsWith(keyIndex)) {
                            readFlag = false;
                            break;
                        }
                    }
                }
                if (readFlag) {
                    readLine = readLine.trim();
                    readLine = readLine.replaceAll(keyIndex, "");
                    readLine = readLine.toLowerCase();

                    if (keyIndex.equals("C1 ")) {
                        Integer start = StringUtils.ordinalIndexOf(readLine, "]", 1);
                        if (start > -1) {
                            readLine = StringUtils.overlay(readLine, "", 0, start + 1);
                            start = StringUtils.ordinalIndexOf(readLine, "]", 1);
                            Integer end = StringUtils.indexOf(readLine, ",", start);
                            readLine = StringUtils.overlay(readLine, "", end, readLine.length());
                            readLine = readLine.trim();
                        }
                    }
                    if (keyIndex.equals("AU ") && Utils.isContainChinese(readLine)) {
                        readLine = readLine.replaceAll(",", ";");
                        readLine = readLine.replaceAll("，", ";");
                    }
                    if (keyIndex.equals("AU ") && !Utils.isContainChinese(readLine)) {
                        if (readLine.endsWith(",")) {
                            readLine = readLine.substring(0, readLine.length() - 1);
                        }
                    } else if (!keyIndex.equals("AU ")) {
                        readLine = readLine.replaceAll(",", ";");
                        readLine = readLine.replaceAll("，", ";");
                    }
                    if (readLine.endsWith(".")) {
                        readLine = readLine.replaceAll("\\.", ";").trim();
                    }
                    sb.append(readLine);
                    if (!readLine.endsWith(";")) {
                        sb.append(";");
                    }
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            close(lineReader);
        }

        return sb.toString();
    }

    public static String replaceByNewWord(File file, String keyIndex, List<String> listWords, List<Mother1Info> bookBatInfos) {
        //参数校验
        verifyParam(file);
//        StringBuilder sb = new StringBuilder();
//        //行读取
//        LineNumberReader lineReader = null;
//        try {
//            lineReader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
//            String readLine = null;
//            boolean readFlag = false;
//            while ((readLine = lineReader.readLine()) != null) {
//                if (readLine.startsWith(keyIndex)) {
//                    readFlag = true;
//                }
//                boolean handleFlag = false;
//                if (readFlag == true) {
//                    for (String index : listWords) {
//                        if (readLine.startsWith(index) && !readLine.startsWith(keyIndex)) {
//                            readFlag = false;
//                            break;
//                        }
//                    }
//                }
//                if (readFlag) {
//                    String handleReadLine = readLine;
//                    for (BookBatInfo bookBatInfo : bookBatInfos) {
//                        String keyword = bookBatInfo.getWord();
//                        String result = bookBatInfo.getHandleResult();
//                        handleReadLine = readLine.trim().replaceAll(keyIndex, "");
////                        if(readLine.trim().endsWith(",") || readLine.trim().endsWith(".") || readLine.trim().endsWith("，")) {
//                        handleReadLine = handleReadLine.replaceAll("\\.", ";").trim();
//                        handleReadLine = handleReadLine.replaceAll(",", ";");
//                        handleReadLine = handleReadLine.replaceAll("，", ";");
////                        }
//                        if (keyIndex.equals("C1 ")) {
//                            Integer start = StringUtils.ordinalIndexOf(readLine, "]", 1);
//                            if (start > -1) {
//                                handleReadLine = StringUtils.overlay(handleReadLine, "", 0, start - 1);
//                                start = StringUtils.ordinalIndexOf(handleReadLine, "]", 1);
//                                Integer end = StringUtils.indexOf(handleReadLine.trim(), ",", start);
//                                handleReadLine = StringUtils.overlay(handleReadLine, "", end, handleReadLine.length());
//                            }
//                        }
//                        Integer index = 0;
//                        List<Integer> sList = new ArrayList();
//                        Collections.sort(sList);
//
//                        int totalLength = readLine.length();
//                        if (readLine.toLowerCase().contains(keyword)) {
//                            while (index < totalLength) {
//                                index = StringUtils.indexOf(readLine.toLowerCase(), keyword, index);
//                                if (index < 0) {
//                                    break;
//                                }
//                                Integer length = keyword.length();
//                                try {
//                                    String nextWord = StringUtils.substring(readLine, index + length, index + length + 1);
//                                    Integer tempNextCount = 0;
//                                    while(nextWord.equals(" ")){
//                                        index++;
//                                        tempNextCount ++;
//                                        nextWord = StringUtils.substring(readLine, index + length, index + length + 1);
//                                    }
//                                    index-=tempNextCount;
//                                    if (!nextWord.equals(";") && !nextWord.equals(",") && !nextWord.equals(".") &&
//                                            !nextWord.equals("，") && !nextWord.equals("")){
//                                        index = index + length + 1;
//                                        continue;
//                                    }
//
//                                } catch (Exception e) {
//
//                                }
//                                try {
//                                    String preWord = StringUtils.substring(readLine, index -1, index);
//                                    Integer tempPreCount = 0;
//                                    while(preWord.equals(" ")){
//                                        index--;
//                                        tempPreCount ++;
//                                        preWord = StringUtils.substring(readLine, index -1, index);
//                                    }
//                                    index+=tempPreCount;
//                                    if(readLine.startsWith(keyIndex)){
//                                        if(index != 3){
//                                            if (!preWord.equals(";") && !preWord.equals(",") && !preWord.equals(".") && !preWord.equals("，")
//                                                    && !preWord.equals("")) {
//                                                index = index + length + 1;
//                                                continue;
//                                            }
//                                        }
//                                    }else{
//                                        if (!preWord.equals(";") && !preWord.equals(",") && !preWord.equals(".") && !preWord.equals("，")
//                                                && !preWord.equals("")) {
//                                            index = index + length + 1;
//                                            continue;
//                                        }
//                                    }
//
//                                }catch (Exception e){
//
//                                }
//                                if (result.equals("")) {
//                                    try {
//                                        if (readLine.substring(index - 1, index).equals(",") || readLine.substring(index - 1, index).equals(";") ||
//                                                readLine.substring(index - 1, index).equals("，") || readLine.substring(index - 1, index).equals(".")) {
//                                            index = index - 1;
//                                            length = length +1;
//                                        }
//                                    } catch (Exception e) {
//                                    }
//                                    try {
//                                        if (readLine.substring(index + length, index + length + 1).equals(",") || readLine.substring(index + length, index + length + 1).equals(";") ||
//                                                readLine.substring(index + length, index + length + 1).equals("，") || readLine.substring(index + length, index + length + 1).equals(".")) {
//                                            length = length + 1;
//                                        }
//                                    } catch (Exception e) {
//
//                                    }
//                                }
//                                readLine = StringUtils.overlay(readLine, result, index, index + length);
//                                handleFlag = true;
//                                index = index + length + 1;
//                            }
//                        }
//                    }
//
//                }
//                if (!readLine.trim().equals("") || !handleFlag) {
//                    sb.append(readLine + "\n");
//                }
//
//            }
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            //关闭流
//            close(lineReader);
//        }
        return null;
    }


    public static ObservableList<Mother1Info> handleWords(File motherFile1) {

        Workbook workbook = null;
        try {
            workbook = WorkbookFactory.create(motherFile1);
        } catch (IOException e) {

        }

        int numberOfSheets = workbook.getNumberOfSheets();

        for (int i = 0; i < numberOfSheets; i++) {
            Sheet sheet = workbook.getSheetAt(i);

            // 行数。
            int rowNumbers = sheet.getLastRowNum() + 1;

            // Excel第一行。
            Row temp = sheet.getRow(0);
            if (temp == null) {
                continue;
            }

            int cells = temp.getPhysicalNumberOfCells();

            List<Mother1Info> li = new ArrayList<>();
            for (int row = 0; row < rowNumbers; row++) {
                Row r = sheet.getRow(row);
                for (int col = 0; col < cells; col++) {
                    Mother1Info bi = new Mother1Info();
//                    bi.setProofDate(r.getCell(col).toString());
//                    System.out.println(bi);
                    ObservableList<Mother1Info> result = FXCollections.observableArrayList(
                            li
                    );
                }
            }
        }


        return null;
    }

    public static ObservableList<Mother1Info> handleWords(String words) {
        String[] word = words.split(";");
        List<String> listWord = Arrays.asList(word);
        List<String> listNewWord = new ArrayList();
        listWord.forEach((x) -> listNewWord.add(x.trim()));
        Map<String, Long> resultMap = listNewWord.stream().filter(x -> !x.equals("")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        List<Mother1Info> li = new ArrayList<>();
        resultMap.forEach((key, value) -> {
            Mother1Info bi = new Mother1Info();

            li.add(bi);
        });
        ObservableList<Mother1Info> result = FXCollections.observableArrayList(
                li
        );
        return result;
    }


    /**
     * 参数校验
     *
     * <br>
     * Date: 2014年11月5日
     */
    private static void verifyParam(File file, String keyword) {
        //对参数进行校验证
        if (file == null) {
            throw new NullPointerException("文件为空");
        }
        if (keyword == null || keyword.trim().equals("")) {
            throw new NullPointerException("the keyword is null or \"\" ");
        }

        if (!file.exists()) {
            throw new RuntimeException("the file is not exists");
        }
        //非目录
        if (file.isDirectory()) {
            throw new RuntimeException("the file is a directory,not a file");
        }

        //可读取
        if (!file.canRead()) {
            throw new RuntimeException("the file can't read");
        }
    }

    private static void verifyParam(File file) {
        //对参数进行校验证
        if (file == null) {
            throw new NullPointerException("文件为空");
        }

        if (!file.exists()) {
            throw new RuntimeException("文件不存在");
        }
        //非目录
        if (file.isDirectory()) {
            throw new RuntimeException("所选为文件夹，不是文件");
        }

        //可读取
        if (!file.canRead()) {
            throw new RuntimeException("文件不可读");
        }
    }

    /**
     * 关闭流
     * <br>
     * Date: 2014年11月5日
     */
    private static void close(Closeable able) {
        if (able != null) {
            try {
                able.close();
            } catch (IOException e) {
                e.printStackTrace();
                able = null;
            }
        }
    }

    public static String alterStringReturnNewString(File file, String oldString,
                                                    String newString, String keyIndex, boolean caseMatch, List<Object> otherKeyIndexList) {
        StringBuilder sb = new StringBuilder();
        try {
            long start = System.currentTimeMillis();
            //创建临时文件
//            File newFile = new File("src/临时文件");
//            if(!newFile.exists()){
//                newFile.createNewFile();
//            }
            //创建随机文件流
            RandomAccessFile raf = new RandomAccessFile(file, "rw");
            //创建对临时文件缓存输出流
//            BufferedWriter bw_NewFile = new BufferedWriter(
//                    new OutputStreamWriter(
//                            new FileOutputStream(newFile,true)));
            String string; //存储读取内容
            long lastPoint = raf.getFilePointer(); //记录每次读取位置
            long point = 0; //记录第一次包含目标字符串位置
            int sum = 0; //记录包含目标字符串次数
            boolean flag = false; //判断是否是目标字符之后内容
            int countFlag = 0;
            String preString = "";
            int line = 0;
            while ((string = raf.readLine()) != null) {
                String trimString = string.trim();
                line++;
                if (line == 0) {
                    preString = string;
                }
                //随机文件流读取的时候会将GBK格式转为ISO-8859-1，
                //将读取的内容转回本地格式

                if (string.startsWith(keyIndex)) {
                    countFlag = 1;
                }
                for (Object otherKey : otherKeyIndexList) {
                    if (string.startsWith(otherKey.toString())) {
                        countFlag = 0;
                        break;
                    }
                }

                if (countFlag == 1) {
                    string = new String(string.getBytes("ISO-8859-1"));
                    //判断是否包含目标字符
                    if (caseMatch == true) {
                        string = string.toUpperCase();
                        oldString = oldString.toUpperCase();
                    }
                    if (string.contains(oldString)) {
                        if (sum == 0)
                            point = lastPoint;
                        if (newString.equals("")) {
//                            string = new String(string.replace(oldString+";", newString));
                            string = new String(trimString.replace(oldString + "; ", newString));
                            string = new String(string.replace(oldString, newString));
                            if (string.equals("")) {
                                if (preString.endsWith(";")) {
                                    String fixString = preString.substring(0, preString.length() - 1);
                                    sb.replace(sb.length() - preString.length() - 1, sb.length(), fixString + "\n");
                                }
                            }
                        } else {
                            string = new String(string.replace(oldString, newString));
                        }
                        if (!string.equals("")) {
                            sb.append(string + "\n");
                        }
                        sum++;
                        flag = true;
                    } else {
                        flag = false;
                    }
                }
                if (!flag || countFlag == 0) {
                    sb.append(string + "\n");
                } else {
                    lastPoint = raf.getFilePointer();
                }

//                raf.seek(point);
                long time = System.currentTimeMillis() - start;
                System.out.println(sum + "个" + oldString
                        + "替换成" + newString + "耗费时间:" + time);
                preString = string;
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return sb.toString();
    }



    public String findNumber(String s){
        String result = "";
        for(int i = 0; i < s.length(); i++){
            int code = s.codePointAt(i);
            if(code >= 48 && code <= 57){
                result += (char)code;
            }
        }
        return result;
    }

    public  static List<Double>  getNumberFromString(String text) {
        List<Double> numbers=new ArrayList<>();
        String pattern="([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])";
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
        // 现在创建 matcher 对象
        Matcher matcher = r.matcher(text);
        Set<String> matchStrs = new HashSet<>();
        while (matcher.find()) {
            //获取当前匹配的值
            matchStrs.add(matcher.group());
        }
        if(matchStrs.size()==0){
            return numbers;
        }
        for(String s:matchStrs){
            try{
                double number=Double.parseDouble(s);
                numbers.add(number);
            }catch(Exception e){
                continue;
            }
        }
        return numbers;
    }

    public  static boolean equalsList(List a,List b){
        if (a.size() !=b.size())
            return false;
        Collections.sort(a);
        Collections.sort(b);
        for (int i = 0; i <a.size(); i++) {
            if(!a.get(i).equals(b.get(i)))
                return false;
        }
        return true;
    }

}
